package com.ssy.lingxi.dataauth.builder;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 万宁
 * @version 2.0.0
 * @date 2021-04-08
 */
public class SqlStringUtil {

    /**
     * 统计子字符串出现的次数
     * @param plainStr 原字符串
     * @param findStr 要查找的子字符串
     * @return 子字符串出现的次数
     */
    public static int count(String plainStr , String findStr) {
        if(plainStr == null || plainStr.length() == 0) {
            return 0;
        }

        int i = plainStr.length() - plainStr.replaceAll(findStr, "").length();
        return  i / findStr.length();
    }

    /**
     * 将Map<String, Object>类型转换为where语句中的查询条件
     * @param map 要转换的map
     * @return where语句中的查询条件
     */
    @SuppressWarnings("unchecked")
    public static String makeWhereClase(Map<String, Object> map, String aliasPrefix) {
        String prefix = aliasPrefix == null || "".equals(aliasPrefix.trim()) ? "" : aliasPrefix;
        List<String> whereList = new ArrayList<>();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            if(Objects.isNull(entry.getValue())) {
                whereList.add(prefix + entry.getKey().concat(" is null"));
                continue;
            }

            if(entry.getValue() instanceof Object[]) {
                List<Object> objects = Arrays.stream((Object[]) entry.getValue()).collect(Collectors.toList());
                whereList.add(prefix + entry.getKey().concat(" in ").concat(makeCollectionValue(objects)));
                continue;
            }

            switch (entry.getValue().getClass().getName()) {
                case "java.lang.Integer":
                case "java.lang.Long":
                case "java.lang.Short":
                case "java.lang.Float":
                case "java.lang.Double":
                case "java.lang.Boolean":
                case "java.math.BigInteger":
                case "java.math.BigDecimal":
                    whereList.add(prefix + entry.getKey().concat(" = ").concat(String.valueOf(entry.getValue())));
                    break;
                case "java.lang.String":
                case "java.time.LocalDate":
                    String value = "'".concat(String.valueOf(entry.getValue())).concat("'");
                    whereList.add(prefix + entry.getKey().concat(" = ").concat(value));
                    break;
                case "java.util.Date":
                    Date dt = (Date) entry.getValue();
                    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    whereList.add(prefix + entry.getKey().concat(" = ").concat("'" + formatter.format(dt) + "'"));
                    break;
                case "java.time.LocalDateTime":
                    LocalDateTime ldt = (LocalDateTime) entry.getValue();
                    whereList.add(prefix + entry.getKey().concat(" = ").concat("'" + ldt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + "'"));
                    break;
                case "java.util.ArrayList":
                    whereList.add(prefix + entry.getKey().concat(" in ").concat(makeCollectionValue((List<Object>) entry.getValue())));
                    break;
                case "java.util.HashSet":
                    whereList.add(prefix + entry.getKey().concat(" in ").concat(makeCollectionValue(new ArrayList<>((HashSet<Object>) entry.getValue()))));
                    break;
                default:
                    break;
            }
        }

        return String.join(" and ", whereList);
    }

    private static String makeCollectionValue(List<Object> list) {
        String result = "";
        List<String> tmpList = new ArrayList<>();
        Object obj = list.get(0);
        switch (obj.getClass().getName()) {
            case "java.lang.Integer":
            case "java.lang.Long":
            case "java.lang.Short":
            case "java.lang.Float":
            case "java.lang.Double":
            case "java.lang.Boolean":
            case "java.math.BigInteger":
            case "java.math.BigDecimal":
                for (Object o : list) {
                    tmpList.add(String.valueOf(o));
                }
                result = "[" + String.join(",", tmpList) + "]";
                break;
            case "java.lang.String":
            case "java.time.LocalDate":
                for (Object o : list) {
                    tmpList.add("'".concat(String.valueOf(o)).concat("'"));
                }
                result = "[" + String.join(",", tmpList) + "]";
                break;
            case "java.util.Date":
                SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                for (Object o : list) {
                    Date dt = (Date) o;
                    tmpList.add("'".concat(formatter.format(dt)).concat("'"));
                }
                result = "[" + String.join(",", tmpList) + "]";
                break;
            case "java.time.LocalDateTime":
                for (Object o : list) {
                    LocalDateTime ldt = (LocalDateTime) o;
                    tmpList.add("'".concat(ldt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))).concat("'"));
                }
                result = "[" + String.join(",", tmpList) + "]";
                break;
            default:
                break;
        }

        return result;
    }

}
